﻿using System.Collections;
using System.Collections.Generic;
using UIFramework;
using UnityEngine;
using XLua;

namespace LuaFramework
{
    /// <summary>
    /// 映射Unity生命周期函数到lua代码对应的方法中
    /// </summary>    
    public class MapLifeCycle : MonoBehaviour
    {
        //存放所有添加了生命周期的集合
        public static List<MapLifeCycle> _AllMapLifeCycle = new List<MapLifeCycle>();
        //委托
        [CSharpCallLua]
        delegate void DeleStartFunction(GameObject go);
        [CSharpCallLua]
        delegate void DeleAwarkFunction(GameObject go);
        [CSharpCallLua]
        delegate void DeleUpdateFunction(GameObject go);
        [CSharpCallLua]
        delegate void DeleEnableFunction(GameObject go);
        [CSharpCallLua]
        delegate void DeleDisableFunction(GameObject go);
        [CSharpCallLua]
        delegate void DeleDestroyFunction(GameObject go);

        DeleStartFunction _StartDelegate;
        DeleAwarkFunction _AwakeDelegate;
        DeleUpdateFunction _UpdateDelegate;
        DeleEnableFunction _EnableDelegate;
        DeleDisableFunction _DisableDelegate;
        DeleDestroyFunction _DestroyDelegate;

        //定义虚拟机和一张lua表
        private LuaEnv _Env;
        private LuaTable table;

        private void Awake()
        {
            //将被类添加在集合中
            _AllMapLifeCycle.Add(this);

            _Env = LuaHelper.Instance.GetLuaEnv();
            table = _Env.NewTable();
            LuaTable temp_table = _Env.NewTable();
            //设置原表为lua全局
            temp_table.Set("__index", _Env.Global);

            table.SetMetaTable(temp_table);
            temp_table.Dispose();
            //当前游戏物体的名字
            string go_name = this.gameObject.name.Replace("(Clone)", "");
            //找到对应lua脚本的指定方法
            _AwakeDelegate = table.GetInPath<DeleAwarkFunction>(go_name + ".Awake");
            _StartDelegate = table.GetInPath<DeleStartFunction>(go_name + ".Start");
            _UpdateDelegate = table.GetInPath<DeleUpdateFunction>(go_name + ".Update");
            _EnableDelegate = table.GetInPath<DeleEnableFunction>(go_name + ".OnEnable");
            _DisableDelegate = table.GetInPath<DeleDisableFunction>(go_name + ".OnDisable");
            _DestroyDelegate = table.GetInPath<DeleDestroyFunction>(go_name + ".OnDestroy");

            if (_AwakeDelegate != null)
            {
                _AwakeDelegate(gameObject);
            }
        }
        void Start()
        {
            if (_StartDelegate != null)
            {
                _StartDelegate(gameObject);
            }
        }
        void Update()
        {
            if (_UpdateDelegate != null)
            {
                _UpdateDelegate(gameObject);
            }
        }

        private void OnDisable()
        {
            if (_DisableDelegate != null)
            {
                _DisableDelegate(gameObject);
            }
        }
        private void OnEnable()
        {
            if (_EnableDelegate != null)
            {
                _EnableDelegate(gameObject);
            }
        }
        private void OnDestroy()
        {
            if (_DestroyDelegate != null)
            {
                _DestroyDelegate(gameObject);
            }
            _StartDelegate = null;
            _AwakeDelegate = null;
            _UpdateDelegate = null;
            _EnableDelegate = null;
            _DisableDelegate = null;
            _DestroyDelegate = null;
            //Debug.Log("释放引用：" + gameObject.name);
        }

        /// <summary>
        /// 手动释放所有的委托引用
        /// </summary>
        public static void HandDisposeAll()
        {
            foreach (var map in _AllMapLifeCycle)
            {
                map._StartDelegate = null;
                map._AwakeDelegate = null;
                map._UpdateDelegate = null;
                map._EnableDelegate = null;
                map._DisableDelegate = null;
                map._DestroyDelegate = null;
            }
        }
    }
}